]> dgit.raspbian.org Git - pcre2.git/commitdiff
Backport of pcre2-10.48-Fix-allocation-byte-sizing.patch
authorIlia Alshanetsky <ilia@ilia.ws>
Sun, 9 Aug 2026 11:15:03 +0000 (07:15 -0400)
committerMatthew Vernon <matthew@debian.org>
Tue, 1 Sep 2026 10:43:48 +0000 (11:43 +0100)
Cherry-pick of 8156b3989a82f2ddf9504d8248496e9b124be7f3

Use CU2BYTES for byte sizing in two allocation sites (#909)

Two allocation sites multiplied by PCRE2_CODE_UNIT_WIDTH (the bit width:
8, 16, or 32) where the CU2BYTES(x) byte-count helper is intended. The
result over-allocates by the code-unit byte width: 8x in 8-bit mode, 16x
in 16-bit, 32x in 32-bit. Subsequent memcpy calls already use CU2BYTES
correctly, so no out-of-bounds write occurs; the over-allocation is
leaked until the buffer is freed.

Also guard each site against integer overflow in
sizeof(pcre2_memctl) + CU2BYTES(N + 1) by rejecting N greater than
(PCRE2_SIZE_MAX - sizeof(pcre2_memctl)) / CU2BYTES(1) - 1.

(cherry picked from commit 31ec59526d641b85108c726fe201effc5dca8627)

src/pcre2_convert.c
src/pcre2_substring.c

index d2b238ca4afb414fbf40ca5c73efc997a846fdda..408049628e7da40b13213d300731177a55503394 100644 (file)
@@ -1148,9 +1148,12 @@ for (int i = 0; i < 2; i++)
   /* Allocate memory for the buffer, with hidden space for an allocator at
   the start. The next time round the loop runs the conversion for real. */
 
-  allocated = PRIV(memctl_malloc)(sizeof(pcre2_memctl) +
-    (*bufflenptr + 1)*PCRE2_CODE_UNIT_WIDTH, (pcre2_memctl *)ccontext);
-  if (allocated == NULL) return PCRE2_ERROR_NOMEMORY;
+  if (*bufflenptr > ((PCRE2_SIZE_MAX - sizeof(pcre2_memctl)) /
+        CU2BYTES(1)) - 1 ||
+      (allocated = PRIV(memctl_malloc)(sizeof(pcre2_memctl) +
+        CU2BYTES(*bufflenptr + 1),
+        (pcre2_memctl *)ccontext)) == NULL)
+    return PCRE2_ERROR_NOMEMORY;
   *buffptr = (PCRE2_UCHAR *)(((char *)allocated) + sizeof(pcre2_memctl));
 
   use_buffer = *buffptr;
index 88afd2348bb3f831e0c51210ca3c01c6592d6557..aabab288b9f637e1cd9d1cdb5cb218a331fc4379 100644 (file)
@@ -214,9 +214,10 @@ PCRE2_SIZE size;
 PCRE2_UCHAR *yield;
 rc = pcre2_substring_length_bynumber(match_data, stringnumber, &size);
 if (rc < 0) return rc;
-yield = PRIV(memctl_malloc)(sizeof(pcre2_memctl) +
-  (size + 1)*PCRE2_CODE_UNIT_WIDTH, (pcre2_memctl *)match_data);
-if (yield == NULL) return PCRE2_ERROR_NOMEMORY;
+if (size > ((PCRE2_SIZE_MAX - sizeof(pcre2_memctl)) / CU2BYTES(1)) - 1 ||
+    (yield = PRIV(memctl_malloc)(sizeof(pcre2_memctl) +
+      CU2BYTES(size + 1), (pcre2_memctl *)match_data)) == NULL)
+  return PCRE2_ERROR_NOMEMORY;
 yield = (PCRE2_UCHAR *)(((char *)yield) + sizeof(pcre2_memctl));
 memcpy(yield, match_data->subject + match_data->ovector[stringnumber*2],
   CU2BYTES(size));